home *** CD-ROM | disk | FTP | other *** search
- /* The following code will broadcast 'Mail for:' beacons
- * for private users with unread mail on a regular interval
- *
- * Also contains the commands to set the R: header read options
- * with the 'bulletin' command.
- *
- * original: 920306
- * rewritten: 920326
- * Copyright 1992, Johan. K. Reinalda, WG7J/PA3DIS
- * Permission granted for non-commercial use only!
- */
- #include "global.h"
- #include "commands.h"
- #ifdef MSDOS
- #include "socket.h"
- #endif
- #include "files.h"
- #include "dirutil.h"
- #include "bm.h"
- #include "x.h"
-
-
- #if !defined(_lint)
- static char rcsid[] OPTIONAL = "$Id: mailfor.c,v 1.32 1997/09/07 21:18:28 root Exp root $";
- #endif
-
- #ifdef MAILFOR
- #ifdef AX25
-
- #define MAXMFLEN 256
- static struct timer Mftimer;
- static char ax_mftext[MAXMFLEN + 1] = "Mail for:";
-
- #define DEFMFLEN 9
- static int mflen = DEFMFLEN; /*Initial lenght of mail-for string*/
-
- #ifdef HOLDMONITOR
- #ifdef SOUNDS
- char *HOLDsound;
- #endif
- int HOLDmode, HOLDindicator;
- #endif
-
- #ifdef ALERTMONITOR
- #ifdef SOUNDS
- static char *ALERTsound;
- #endif
- static int ALERTmode;
- int ALERTindicator;
- #endif
-
- extern int CountConfUsers (void);
- static int checknewmail (char *area);
- static int mf_exclude (char *name);
- static void countMessages (void);
- static int setmailfor (void);
- static void ax_mf (struct iface * ifp);
- static void Mftick (void *v);
- int dombmailfor (int argc, char **argv, void *p);
- int indexFwdBbs (char *name);
-
-
- static struct no_mf *No_mf = NULLMF;
-
- #ifdef ALERTMONITOR
- static struct mfalert *mf_alerts = NULLMFA;
- #endif
-
-
- /*Read a private message area's control file, searching for unread mail
- *this is indicated by the status int
- */
-
- static int
- checknewmail (char *area)
- {
- FILE *fp;
- char mailbox[100];
- long size;
- int i, nmsgs;
- struct let *cmsg;
- struct let *new;
- int ret = 0;
-
- sprintf (mailbox, "%s/control/%s.ctl", Mailspool, area);
- if ((fp = fopen (mailbox, READ_BINARY)) != NULLFILE) {
- size = (long) filelength (fileno (fp));
- new = (struct let *) mallocw ((unsigned int) size);
- kwait (NULL);
- (void) fread (new, (unsigned int) size, 1, fp);
- (void) fclose (fp);
- kwait (NULL);
- nmsgs = (int) (size / (long) sizeof (struct let));
-
- for (cmsg = new, i = 0; i < nmsgs; i++, cmsg++) {
- if (!(cmsg->status & BM_READ)) {
- ret = 1;
- break;
- }
- }
- free (new);
- }
- return ret;
- }
-
-
- /* Check name with exclude list;
- * returns 1 if found, 0 if not
- */
- static int
- mf_exclude (char *name)
- {
- struct no_mf *nm;
-
- /*Now check the 'exclude' list*/
- for (nm = No_mf; nm != NULLMF; nm = nm->next) {
- if (!stricmp (nm->area, name))
- return 1;
- }
- return 0;
- }
-
-
- #ifdef CONVERS
- static char ActiveMessages[] = "Active Messages: %ld (%s in conference sessions)";
- #else
- static char ActiveMessages[] = "Active Messages: %ld";
- #endif
- static long ACTIVEMessages = 0;
-
- static void
- countMessages (void)
- {
- char buf[128];
- struct ffblk ff;
- long size;
-
- ACTIVEMessages = 0;
- sprintf (buf, "%s/control/*.ctl", Mailspool);
- if (findfirst (buf, &ff, 0) == 0) {
- do {
- kwait (NULL); /* Let others run */
- sprintf (buf, "%s/control/%s", Mailspool, ff.ff_name);
- size = fsize (buf);
- ACTIVEMessages += (size / 14L);
- } while (findnext (&ff) == 0);
- }
- }
-
-
- static int
- setmailfor (void)
- {
- char buf[80];
- struct ffblk ff;
- char *cp;
-
- sprintf (buf, "%s/*.txt", Mailspool);
- if (findfirst (buf, &ff, 0) == 0) {
- do {
- kwait (NULL); /* Let others run */
- cp = strrchr (ff.ff_name, '.');
- if (cp) /* should always be true */
- *cp = '\0';
- /*must be private mail area, and not on exclude list !*/
- if (!issysarea (ff.ff_name) && !mf_exclude (ff.ff_name)) {
- if ((strlen (ax_mftext) + strlen (ff.ff_name)) > MAXMFLEN - 1)
- break; /* That's all folks */
- if (checknewmail (ff.ff_name)) {
- strcat (ax_mftext, " ");
- strcat (ax_mftext, ff.ff_name);
- }
- }
- } while (findnext (&ff) == 0);
- }
- countMessages ();
-
- return (int) strlen (ax_mftext);
- }
-
-
- /*This is the low-level broadcast function.*/
- static void
- ax_mf (struct iface *ifp)
- {
- struct mbuf *bp;
- #ifdef CONVERS
- int inconference = 0;
- char fakestr[8];
- #endif
-
- /* prepare the header */
- if ((bp = alloc_mbuf ((int16) mflen)) == NULLBUF)
- return;
-
- /*copy the data into the packet*/
- bp->cnt = (int16) mflen;
- memcpy (bp->data, ax_mftext, (unsigned int) mflen);
-
- /* send it */
- (void) (*ifp->output) (ifp, Ax25multi[MAILCALL], ifp->hwaddr, PID_NO_L3, bp);
-
-
- /* prepare the header */
- if ((bp = alloc_mbuf ((int16) (strlen (ActiveMessages) + 16))) == NULLBUF)
- return;
-
- /*copy the data into the packet*/
- #ifdef CONVERS
- inconference = CountConfUsers ();
- sprintf ((char *) bp->data, ActiveMessages, ACTIVEMessages, (inconference) ? itoa (inconference, fakestr, 10) : "NONE");
- #else
- sprintf (bp->data, ActiveMessages, ACTIVEMessages);
- #endif
- bp->cnt = (int16) strlen ((char *) bp->data);
-
- /* send it */
- (void) (*ifp->output) (ifp, Ax25multi[MAILCALL], ifp->hwaddr, PID_NO_L3, bp);
- }
-
-
- static void
- Mftick (void *v OPTIONAL)
- {
- struct iface *ifp = Ifaces;
-
- stop_timer (&Mftimer); /* in case this was 'kicked' with a 'mailfor now'*/
-
- /* Now find private mail areas with unread mail. add these to the info-line */
- ax_mftext[DEFMFLEN] = '\0'; /* Back to only 'Mail for:' again*/
-
- if ((mflen = setmailfor ()) < DEFMFLEN + 1) {
- start_detached_timer (&Mftimer);
- return; /* No unread mail */
- }
-
- /*broadcast it on all configured interfaces*/
- for (ifp = Ifaces; ifp != NULL; ifp = ifp->next)
- if (ifp->flags & MAIL_BEACON)
- ax_mf (ifp);
- /* Restart timer */
- start_detached_timer (&Mftimer);
- }
-
-
- #ifdef ALERTMONITOR
- static int domfalert (int argc, char *argv[], void *p);
- #endif
- static int domfexclude (int argc, char *argv[], void *p);
- #ifdef HOLDMONITOR
- static int domfhold (int argc, char *argv[], void *p);
- #endif
- static int domfnow (int argc, char *argv[], void *p);
- int domflist (int argc, char *argv[], void *p);
-
-
- static struct cmds MFORtab[] =
- {
- #ifdef ALERTMONITOR
- { "alert", domfalert, 0, 0, NULLCHAR },
- #endif
- { "exclude", domfexclude, 0, 0, NULLCHAR },
- #ifdef HOLDMONITOR
- { "hold", domfhold, 0, 0, NULLCHAR },
- #endif
- { "listing", domflist, 0, 0, NULLCHAR },
- { "now", domfnow, 256, 0, NULLCHAR },
- { "timer", domftimer, 0, 0, NULLCHAR },
- { NULLCHAR, NULL, 0, 0, NULLCHAR }
- };
-
-
- int
- dombmailfor (int argc, char *argv[], void *p)
- {
- return subcmd (MFORtab, argc, argv, p);
- }
-
-
- int
- domflist (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- if (mflen > DEFMFLEN)
- tprintf ("%s\n", ax_mftext);
- return 0;
- }
-
-
- int
- domftimer (int argc, char *argv[], void *p OPTIONAL)
- {
- #ifdef CONVERS
- int inconference = 0;
- char fakestr[8];
- #endif
-
- if (argc < 2) { /* set the timer */
- tprintf ("Mail-for timer: %lu/%lu\n", read_timer (&Mftimer) / 1000L,
- dur_timer (&Mftimer) / 1000L);
- if (ACTIVEMessages) {
- #ifdef CONVERS
- inconference = CountConfUsers ();
- tprintf (ActiveMessages, ACTIVEMessages, (inconference) ? itoa (inconference, fakestr, 10) : "NONE");
- #else
- tprintf (ActiveMessages, ACTIVEMessages);
- #endif
- tputs ("\n");
- }
- if (mflen > DEFMFLEN)
- tprintf ("%s\n", ax_mftext);
- tputs ("\n");
- return 0;
- }
- Mftimer.func = (void (*)(void *)) Mftick; /* what to call on timeout */
- Mftimer.arg = NULL; /* dummy value */
- set_timer (&Mftimer, atol (argv[1]) * 1000L); /* set timer duration */
- start_detached_timer (&Mftimer);
- return 0;
- }
-
-
- int
- domfnow (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- Mftick (NULL);
- return 0;
- }
-
-
- int
- domfexclude (int argc, char *argv[], void *p OPTIONAL)
- {
- struct no_mf *nm;
- int i;
-
- if (argc == 1) { /*just list them*/
- for (nm = No_mf; nm != NULLMF; nm = nm->next)
- tprintf ("%s ", nm->area);
- tputc ('\n');
- } else { /*add some call(s)*/
- for (i = 1; i < argc; i++) {
- if (strlen (argv[i]) > 8) {
- tprintf ("Invalid: %s\n", argv[i]);
- continue;
- }
- nm = callocw (1, sizeof (struct no_mf));
-
- strncpy (nm->area, argv[i], 20);
- /* add to list */
- nm->next = No_mf;
- No_mf = nm;
- }
- }
- return 0;
- }
-
-
- #ifdef HOLDMONITOR
- static int domfhmode (int argc, char *argv[], void *p);
- static int domfhclear (int argc, char *argv[], void *p);
- static int domfhstatus (int argc, char *argv[], void *p);
- #ifdef SOUNDS
- static int domfhsound (int argc, char *argv[], void *p);
- #endif
-
- static struct cmds MFHOLDtab[] =
- {
- { "clear", domfhclear, 0, 0, NULLCHAR },
- { "mode", domfhmode, 0, 0, NULLCHAR },
- #ifdef SOUNDS
- { "sound", domfhsound, 0, 0, NULLCHAR },
- #endif
- { "status", domfhstatus, 0, 0, NULLCHAR },
- { NULLCHAR, NULL, 0, 0, NULLCHAR }
- };
-
-
- int
- domfhold (int argc, char *argv[], void *p)
- {
- return subcmd (MFHOLDtab, argc, argv, p);
- }
-
-
- int
- domfhclear (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- HOLDindicator = 0;
- #ifdef XSERVER
- xnotify (X_HOLD);
- #endif
- return 0;
- }
-
-
- int
- domfhmode (int argc, char *argv[], void *p OPTIONAL)
- {
- return setbool (&HOLDmode, "Monitoring for HELD messages", argc, argv);
- }
-
-
- int
- domfhstatus (int argc, char *argv[], void *p OPTIONAL)
- {
- return setbool (&HOLDindicator, "HELD messages status", argc, argv);
- }
-
-
- #ifdef SOUNDS
- int
- domfhsound (int argc, char *argv[], void *p OPTIONAL)
- {
- return (setsoundstr (argc, argv, &HOLDsound));
- }
-
- #endif /* SOUNDS */
-
- #endif /* HOLDMONITOR */
-
-
- #ifdef ALERTMONITOR
- static int domfaclear (int argc, char *argv[], void *p);
- static int domfambox (int argc, char *argv[], void *p);
- static int domfamode (int argc, char *argv[], void *p);
- static int domfastatus (int argc, char *argv[], void *p);
- #ifdef SOUNDS
- static int domfasound (int argc, char *argv[], void *p);
- #endif
-
-
- static struct cmds MFALERTtab[] =
- {
- { "clear", domfaclear, 0, 0, NULLCHAR },
- { "mbox", domfambox, 0, 0, NULLCHAR },
- { "mode", domfamode, 0, 0, NULLCHAR },
- #ifdef SOUNDS
- { "sound", domfasound, 0, 0, NULLCHAR },
- #endif
- { "status", domfastatus, 0, 0, NULLCHAR },
- { NULLCHAR, NULL, 0, 0, NULLCHAR }
- };
-
-
- int
- domfalert (int argc, char *argv[], void *p)
- {
- return subcmd (MFALERTtab, argc, argv, p);
- }
-
-
- int
- domfaclear (int argc OPTIONAL, char *argv[] OPTIONAL, void *p OPTIONAL)
- {
- ALERTindicator = 0;
- #ifdef XSERVER
- xnotify (X_ALERT);
- #endif
- return 0;
- }
-
-
- int
- domfamode (int argc, char *argv[], void *p OPTIONAL)
- {
- return setbool (&ALERTmode, "Alerting of incoming messages to defined areas", argc, argv);
- }
-
-
- int
- domfastatus (int argc, char *argv[], void *p OPTIONAL)
- {
- return setbool (&ALERTindicator, "Incoming message alert", argc, argv);
- }
-
-
- int
- domfambox (int argc, char *argv[], void *p OPTIONAL)
- {
- struct mfalert *mf;
- int i;
-
- if (argc == 1) { /*just list them*/
- for (mf = mf_alerts; mf != NULLMFA; mf = mf->next)
- tprintf ("%s ", mf->area);
- tputc ('\n');
- } else { /*add some area(s)*/
- for (i = 1; i < argc; i++) {
- if (strlen (argv[i]) > 8) {
- tprintf ("Invalid: %s\n", argv[i]);
- continue;
- }
- mf = callocw (1, sizeof (struct mfalert));
-
- strncpy (mf->area, argv[i], 20);
- /* add to list */
- mf->next = mf_alerts;
- mf_alerts = mf;
- }
- }
- return 0;
- }
-
-
- #ifdef SOUNDS
- int
- domfasound (int argc, char *argv[], void *p OPTIONAL)
- {
- return (setsoundstr (argc, argv, &ALERTsound));
- }
-
- #endif /* SOUNDS */
-
-
- void
- alertarea (char *area)
- {
- struct mfalert *mf;
-
- if (!ALERTmode)
- return;
- for (mf = mf_alerts; mf != NULLMFA; mf = mf->next) {
- if (!stricmp (area, mf->area)) {
- ALERTindicator = 1;
- #ifdef XSERVER
- xnotify (X_ALERT);
- #endif
- #ifdef SOUNDS
- (void) playsound (ALERTsound);
- #endif
- }
- }
-
- }
-
- #endif /* ALERTMONITOR */
-
- #endif /* AX25 */
- #endif /* MAILFOR */
-
-
- /*************************************************************************/
-
- int BBSlookup (char *bbs);
-
- struct bbs MyFwds[NUMFWDBBS];
- int Numfwds = 0;
-
- #ifdef RLINE
-
- /* Depending on the flag set, the mailbox will
- * read the message's original date,
- * the correct 'from' address (instead of the user%forwardbbs@myhost),
- * and for buls set the X-Forwarded options to prevent
- * unneccesary forward attempts
- * all from the R: lines supplied by the bbs system
- * 920311 - WG7J
- */
- static int dobulrdate (int argc, char *argv[], void *p);
- static int dorreturn (int argc, char *argv[], void *p);
- static int dombloophold (int argc, char *argv[], void *p);
- static int dofwdcheck (int argc, char *argv[], void *p);
- static int dombhold (int argc, char *argv[], void *p);
-
- int Rdate = 0;
- int Rreturn = 0;
- int Rfwdcheck = 1;
-
- static struct cmds Rlinetab[] =
- {
- { "check", dofwdcheck, 0, 0, NULLCHAR },
- { "date", dobulrdate, 0, 0, NULLCHAR },
- { "hold", dombhold, 0, 0, NULLCHAR },
- { "loophold", dombloophold, 0, 0, NULLCHAR },
- { "return", dorreturn, 0, 0, NULLCHAR },
- { NULLCHAR, NULL, 0, 0, NULLCHAR }
- };
-
- void ReadFwdBbs (void);
-
-
- static int
- dobulrdate (int argc, char *argv[], void *p OPTIONAL)
- {
- return setbool (&Rdate, "Use R: for orig. date", argc, argv);
- }
-
-
- int Mbloophold = 2;
-
- /* set loop detection threshold - WG7J */
- static int
- dombloophold (int argc, char *argv[], void *p OPTIONAL)
- {
- return setint (&Mbloophold, "Loop hold after", argc, argv);
- }
-
-
- static int
- dorreturn (int argc, char *argv[], void *p OPTIONAL)
- {
- return setbool (&Rreturn, "Use R: for ret. addr.", argc, argv);
- }
-
-
- static int
- dofwdcheck (int argc, char *argv[], void *p OPTIONAL)
- {
- register int i;
-
- (void) setbool (&Rfwdcheck, "Use R: to check buls", argc, argv);
- if ((argc == 1) && Rfwdcheck && Numfwds) { /*list the bbses we check*/
- tputs ("Checking for:");
- for (i = 0; i < Numfwds; i++)
- tprintf (" %s", MyFwds[i].name);
- tputc ('\n');
- } else {
- if (Rfwdcheck)
- ReadFwdBbs ();
- }
- return 0;
- }
-
-
- static int
- dombhold (int argc, char *argv[], void *p OPTIONAL)
- {
- return setbool (&MbHolding, "Hold local bulletins for review", argc, argv);
- }
-
-
- int
- dombrline (int argc, char **argv, void *p)
- {
- return subcmd (Rlinetab, argc, argv, p);
- }
-
-
- #endif
-
-
- #if defined(RLINE) || defined(MBFWD)
- int
- indexFwdBbs (char *name)
- {
- int k;
-
- for (k = 0; k < Numfwds; k++) {
- if (!stricmp (MyFwds[k].name, name))
- break;
- }
- if (k == Numfwds)
- k = NUMFWDBBS;
- return k;
- }
-
-
- void
- ReadFwdBbs (void)
- {
- struct fwdbbs *f;
-
- #if 0
- Numfwds = 0; /* reset - doing this breaks the 'for laston' command */
- #endif
- while (Numfwds < NUMFWDBBS) {
- f = fwdread (NULLCHAR, Numfwds); /* get first BBS entry */
- if (f == NULLFWDBBS)
- break;
- if (indexFwdBbs (f->name) == NUMFWDBBS) {
- MyFwds[Numfwds].subchannel = f->subchannel;
- MyFwds[Numfwds].laston = (time_t) 0;
- strncpy (MyFwds[Numfwds++].name, strupr (f->name), FWDBBSLEN);
- }
- #ifdef MBFWD
- fwdfree (&f);
- #endif
- }
-
- return;
- }
-
- #endif /* RLINE */
-
-
- int
- BBSlookup (char *bbs)
- {
- int retval;
-
- for (retval = 0; retval < Numfwds; retval++)
- if (!stricmp (MyFwds[retval].name, bbs))
- break;
- if (retval == Numfwds)
- return -1;
- else
- return retval;
- }
-